package com.cyl.h5.controller;


import com.cyl.h5.domain.dto.PayNotifyMessageDTO;
import com.cyl.h5.service.H5OrderService;
import com.cyl.manager.oms.service.AftersaleService;
import com.cyl.manager.vip.service.IVipOrderService;
import com.cyl.wechat.WechatPayUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Map;

/**
 * 订单表Controller
 *
 * @author sjm
 * @date 2023-04-05
 */
@Api(description ="微信回调接口列表")
@RestController
@RequestMapping("/no-auth/wechat")
public class PayNotifyController {
    private static final Logger log = LoggerFactory.getLogger(PayNotifyController.class);

    @Autowired
    private H5OrderService h5OrderService;
    @Autowired
    private AftersaleService aftersaleService;

    @Autowired
    private IVipOrderService vipOrderService;

    private final SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");

    /**
     * 微信支付回调 (V3版本)
     * @param request
     * @throws IOException
     */
    @ApiOperation("微信支付回调")
    @PostMapping("/notify")
    public String weChatPayNotify(HttpServletRequest request) throws Exception {
        log.info("======= 收到了微信支付回调 =======");

        try {
            // 读取请求体
            StringBuilder requestBody = new StringBuilder();
            String line;
            BufferedReader reader = request.getReader();
            while (null != (line = reader.readLine())) {
                requestBody.append(line);
            }

            String notifyData = requestBody.toString();
            log.info("【微信支付回调数据】" + notifyData);

            // 验证签名
            if (!WechatPayUtil.isWechatPayNotifyValid(notifyData)) {
                log.error("微信支付回调签名验证失败");
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名验证失败]]></return_msg></xml>";
            }

            // 解析XML数据
            Map<String, String> notifyMap = WechatPayUtil.xmlToMap(notifyData);

            // 检查返回码
            if (!"SUCCESS".equals(notifyMap.get("return_code"))) {
                log.error("微信支付回调返回码失败: " + notifyMap.get("return_msg"));
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[返回码失败]]></return_msg></xml>";
            }

            // 构造回调消息对象
            PayNotifyMessageDTO message = new PayNotifyMessageDTO();
            message.setOutTradeNo(Long.valueOf(notifyMap.get("out_trade_no")));
            message.setMemberId(Long.valueOf(notifyMap.get("attach")));
            message.setTradeStatus(notifyMap.get("trade_state"));
            message.setPayTime(formatter.parse(notifyMap.get("time_end")));
            message.setTradeNo(notifyMap.get("transaction_id"));

            log.info("准备处理支付回调，订单号: {}, 用户ID: {}",
                    message.getOutTradeNo(), message.getMemberId());

            try {
                h5OrderService.payCallBack(message);
                log.info("支付回调处理成功，订单号: {}", message.getOutTradeNo());
                // 返回成功响应
                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            } catch (Exception e) {
                log.error("处理支付回调异常，订单号: " + message.getOutTradeNo(), e);
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理失败]]></return_msg></xml>";
            }
        } catch (Exception e) {
            log.error("处理微信支付回调时发生未预期异常", e);
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[系统异常]]></return_msg></xml>";
        }
    }

    /**
     * 微信支付回调 (V3版本)
     * @param request
     * @throws IOException
     */
    @ApiOperation("微信支付回调")
    @PostMapping("/vip/notify")
    public String vipweChatPayNotify(HttpServletRequest request) throws Exception {
        log.info("======= 收到了微信支付回调 =======");

        try {
            // 读取请求体
            StringBuilder requestBody = new StringBuilder();
            String line;
            BufferedReader reader = request.getReader();
            while (null != (line = reader.readLine())) {
                requestBody.append(line);
            }

            String notifyData = requestBody.toString();
            log.info("【微信支付回调数据】" + notifyData);

            // 验证签名
            if (!WechatPayUtil.isWechatPayNotifyValid(notifyData)) {
                log.error("微信支付回调签名验证失败");
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名验证失败]]></return_msg></xml>";
            }

            // 解析XML数据
            Map<String, String> notifyMap = WechatPayUtil.xmlToMap(notifyData);

            // 检查返回码
            if (!"SUCCESS".equals(notifyMap.get("return_code"))) {
                log.error("微信支付回调返回码失败: " + notifyMap.get("return_msg"));
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[返回码失败]]></return_msg></xml>";
            }

            // 构造回调消息对象
            PayNotifyMessageDTO message = new PayNotifyMessageDTO();
            message.setStringoutTradeNo(notifyMap.get("out_trade_no"));
            message.setMemberId(Long.valueOf(notifyMap.get("attach")));
            message.setTradeStatus(notifyMap.get("return_code"));
            message.setPayTime(formatter.parse(notifyMap.get("time_end")));
            message.setTradeNo(notifyMap.get("transaction_id"));


            try {
                vipOrderService.paySuccessCallback(message);
                log.info("支付回调处理成功，订单号: {}", message.getStringoutTradeNo());
                // 返回成功响应
                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            } catch (Exception e) {
                log.error("处理支付回调异常，订单号: " + message.getStringoutTradeNo(), e);
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理失败]]></return_msg></xml>";
            }
        } catch (Exception e) {
            log.error("处理微信支付回调时发生未预期异常", e);
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[系统异常]]></return_msg></xml>";
        }
    }
    /**
     * 微信退款回调 (V2版本)
     * @param request
     * @throws IOException
     */
    @ApiOperation(value = "微信退款回调")
    @PostMapping("/weChatRefundNotify")
    public String weChatRefundNotify(HttpServletRequest request) throws Exception {
        log.info("收到了微信退款回调");

        // 读取请求体
        StringBuilder requestBody = new StringBuilder();
        String line;
        BufferedReader reader = request.getReader();
        while (null != (line = reader.readLine())) {
            requestBody.append(line);
        }

        String notifyData = requestBody.toString();
        log.info("【微信退款回调数据】" + notifyData);

        // 验证签名
        if (!WechatPayUtil.isWechatPayNotifyValid(notifyData)) {
            log.error("微信退款回调签名验证失败");
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名验证失败]]></return_msg></xml>";
        }

        // 解析XML数据
        Map<String, String> notifyMap = WechatPayUtil.xmlToMap(notifyData);

        // 检查返回码
        if (!"SUCCESS".equals(notifyMap.get("return_code"))) {
            log.error("微信退款回调返回码失败: " + notifyMap.get("return_msg"));
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[返回码失败]]></return_msg></xml>";
        }

        try {
            // 调用退款处理服务
            aftersaleService.refundOrderExc(notifyMap);
            // 返回成功响应
            return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        } catch (Exception e) {
            log.error("处理退款回调异常", e);
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理失败]]></return_msg></xml>";
        }
    }
}
